﻿using Microsoft.Extensions.Caching.Memory;

namespace Services
{
    public interface IDataVLogic
    {
        object GetSummaryStatusVal(StatusMonitor_LightType type);
        object GetSummaryPie();
        object GetDepartmentCnt();
        object GetWireropeCnt();
        object GetSortName(int sort);
        object GetHealthBili(int sort);
        object GetDepartmentPoint();
        object GetProvinceCnt();
        object GetAllDepartmentCnt();
        object GetStatusNameValue(string status);
        object GetStatusRemark(string status);
        object GetStatusPie(string status);
    }

    public class DataVLogic : IDataVLogic
    {
        #region Ioc
        private readonly ICurrentUser _currentUser;
        private readonly ICheckWireropeStatusMonitorRepository _ICheckWireropeStatusMonitorRepository;
        private readonly IDepartmentRepository _IDepartmentRepository;
        private readonly IUsingWireropeRepository _IUsingWireropeRepository;
        private readonly IAreaRepository _areaRepository;
        private readonly IAreaMapping _areaMapping;
        private readonly IProvinceRepository _provinceRepository;
        private readonly IProvinceMapping _provinceMapping;
        private readonly IStandStatusRepository _standStatusRepository;
        private readonly IStandStatusMapping _standStatusMapping;

        private readonly IMemoryCache _cache;

        public DataVLogic(ICheckWireropeStatusMonitorRepository iCheckWireropeStatusMonitorRepository,
                          IDepartmentRepository iDepartmentRepository,
                          IUsingWireropeRepository iUsingWireropeRepository,
                          ICurrentUser currentUser,
                          IAreaRepository areaRepository,
                          IProvinceRepository provinceRepository,
                          IAreaMapping areaMapping,
                          IProvinceMapping provinceMapping,
                          IMemoryCache cache,
                          IStandStatusRepository standStatusRepository,
                          IStandStatusMapping standStatusMapping)
        {
            _ICheckWireropeStatusMonitorRepository = iCheckWireropeStatusMonitorRepository;
            _IDepartmentRepository = iDepartmentRepository;
            _IUsingWireropeRepository = iUsingWireropeRepository;
            _currentUser = currentUser;
            _areaRepository = areaRepository;
            _provinceRepository = provinceRepository;
            _areaMapping = areaMapping;
            _provinceMapping = provinceMapping;
            _cache = cache;
            _standStatusRepository = standStatusRepository;
            _standStatusMapping = standStatusMapping;
        }
        #endregion

        #region 获取钢丝绳综合状态
        public object GetSummaryStatusVal(StatusMonitor_LightType type)
        {
            var allData = _ICheckWireropeStatusMonitorRepository.GetInUsedAll(null);

            int val = -1;
            switch (type)
            {
                case StatusMonitor_LightType.绿:
                    val = allData.Count(x => x.Summary.HasValue && x.Summary.Value == (int)StatusMonitor_LightType.绿);
                    break;

                case StatusMonitor_LightType.蓝:
                    val = allData.Count(x => x.Summary.HasValue && x.Summary.Value == (int)StatusMonitor_LightType.蓝);
                    break;

                case StatusMonitor_LightType.黄:
                    val = allData.Count(x => x.Summary.HasValue && x.Summary.Value == (int)StatusMonitor_LightType.黄);
                    break;

                case StatusMonitor_LightType.橙:
                    val = allData.Count(x => x.Summary.HasValue && x.Summary.Value == (int)StatusMonitor_LightType.橙);
                    break;

                case StatusMonitor_LightType.灰:
                    val = allData.Count(x => x.Summary.HasValue && x.Summary.Value == (int)StatusMonitor_LightType.灰);
                    break;
            }

            return new { Value = val };
        }
        #endregion

        #region 获取钢丝绳综合状态饼图
        public object GetSummaryPie()
        {
            var allData = _ICheckWireropeStatusMonitorRepository.GetInUsedAll(null);
            var allCount = allData.Count(x => x.Summary.HasValue);

            var green = allData.Count(x => x.Summary.HasValue && x.Summary.Value == (int)StatusMonitor_LightType.绿);
            var blue = allData.Count(x => x.Summary.HasValue && x.Summary.Value == (int)StatusMonitor_LightType.蓝);
            var yellow = allData.Count(x => x.Summary.HasValue && x.Summary.Value == (int)StatusMonitor_LightType.黄);
            var orange = allData.Count(x => x.Summary.HasValue && x.Summary.Value == (int)StatusMonitor_LightType.橙);
            var grey = allData.Count(x => x.Summary.HasValue && x.Summary.Value == (int)StatusMonitor_LightType.灰);

            return new List<object>
            {
                new { name="轻度",value=green},
                new { name="中度",value=blue},
                new { name="重度",value=yellow},
                new { name="严重",value=orange},
                new { name="报废",value=grey}
            };
        }
        #endregion

        #region 获取矿山数量
        public object GetDepartmentCnt()
        {
            //得到当前登录用户所对应的部门（矿山）信息
            var departmentWhere = Expressionable.Create<Department>();
            departmentWhere = departmentWhere.And(x => x.Type == (int)Department_Type.矿山);
            if (_currentUser.CurrentUserInfo.LoginUserKuangShanDepartment.Item1 == false)
            {
                departmentWhere = departmentWhere.And(x => _currentUser.CurrentUserInfo.LoginUserKuangShanDepartment.Item2.Contains(x.DepartmentID));
            }
            var cnt = _IDepartmentRepository.GetCount(departmentWhere);

            return new { Value = cnt };
        }
        #endregion

        #region 获取钢丝绳数量
        public object GetWireropeCnt()
        {
            //得到当前登录用户所对应的部门（矿山）信息
            var departmentWhere = Expressionable.Create<Department>();
            departmentWhere = departmentWhere.And(x => x.Type == (int)Department_Type.矿山);
            if (_currentUser.CurrentUserInfo.LoginUserKuangShanDepartment.Item1 == false)
            {
                departmentWhere = departmentWhere.And(x => _currentUser.CurrentUserInfo.LoginUserKuangShanDepartment.Item2.Contains(x.DepartmentID));
            }
            var departments = _IDepartmentRepository.GetSearch(departmentWhere);
            var departmentIDs = departments.Select(x => x.DepartmentID).ToList();

            //得到当前登录用户所对应的部门（矿山）中所包含的钢丝绳信息
            var usingWireropeWhere = Expressionable.Create<UsingWirerope>();
            usingWireropeWhere = usingWireropeWhere.And(x => x.Status == (int)UsingWirerope_Status.在用 && departmentIDs.Contains(x.DepartmentID));
            var cnt = _IUsingWireropeRepository.GetCount(usingWireropeWhere);

            return new { Value = cnt };
        }
        #endregion

        #region 获取排名名次及名称
        public object GetSortName(int sort)
        {
            //得到当前登录用户所对应的部门（矿山）信息
            var departmentWhere = Expressionable.Create<Department>();
            departmentWhere = departmentWhere.And(x => x.Type == (int)Department_Type.矿山);
            if (_currentUser.CurrentUserInfo.LoginUserKuangShanDepartment.Item1 == false)
            {
                departmentWhere = departmentWhere.And(x => _currentUser.CurrentUserInfo.LoginUserKuangShanDepartment.Item2.Contains(x.DepartmentID));
            }
            var departments = _IDepartmentRepository.GetSearch(departmentWhere);
            var departmentIDs = departments.Select(x => x.DepartmentID).ToList();

            var item = _ICheckWireropeStatusMonitorRepository.GetDataByDepartmentIDs("x.SummaryVal desc", sort, departmentIDs.ToArray());
            if (item.IsEmpty())
            {
                return new { Value=$"{sort}   未知名称" };
            }

            return new { Value = $"{sort}   {item.UsingWireropeCode}" };
        }
        #endregion

        #region 获取健康程度比例
        public object GetHealthBili(int sort)
        {
            //得到当前登录用户所对应的部门（矿山）信息
            var departmentWhere = Expressionable.Create<Department>();
            departmentWhere = departmentWhere.And(x => x.Type == (int)Department_Type.矿山);
            if (_currentUser.CurrentUserInfo.LoginUserKuangShanDepartment.Item1 == false)
            {
                departmentWhere = departmentWhere.And(x => _currentUser.CurrentUserInfo.LoginUserKuangShanDepartment.Item2.Contains(x.DepartmentID));
            }
            var departments = _IDepartmentRepository.GetSearch(departmentWhere);
            var departmentIDs = departments.Select(x => x.DepartmentID).ToList();

            var item = _ICheckWireropeStatusMonitorRepository.GetDataByDepartmentIDs("x.SummaryVal desc", sort, departmentIDs.ToArray());
            if (item.IsEmpty())
            {
                return new { Value = 0, Text = string.Empty };
            }

            var val = item.SummaryVal.Value > 1 ? 1 : Math.Truncate(item.SummaryVal.Value * 100) / 100;
            var text = Math.Truncate(item.SummaryVal.Value * 100) / 100;

            return new { Value = val, Text = text };
        }
        #endregion

        #region 获取地图矿山点数据
        public object GetDepartmentPoint()
        {
            //得到当前登录用户所对应的部门（矿山）信息
            var departmentWhere = Expressionable.Create<Department>();
            departmentWhere = departmentWhere.And(x => x.Type == (int)Department_Type.矿山);
            if (_currentUser.CurrentUserInfo.LoginUserKuangShanDepartment.Item1 == false)
            {
                departmentWhere = departmentWhere.And(x => _currentUser.CurrentUserInfo.LoginUserKuangShanDepartment.Item2.Contains(x.DepartmentID));
            }
            var departments = _IDepartmentRepository.GetSearch(departmentWhere);

            //获取区域的信息
            var areaIDs = departments.Where(x => x.AreaID.HasValue).Select(x => x.AreaID.Value).Distinct().ToList();
            var areas = _areaRepository.GetSearch(_areaMapping.FilterModel2Where(new AreaFilterModel { _AreaIDs = areaIDs }));

            return departments.Select(x => new object[] {
                areas.First(y=>y.AreaID==x.AreaID).Longitude,
                areas.First(y=>y.AreaID==x.AreaID).Latitude,
                x.Name
            });
        }
        #endregion

        #region 获取区域占比情况
        public object GetProvinceCnt()
        {
            //得到当前登录用户所对应的部门（矿山）信息
            var departmentWhere = Expressionable.Create<Department>();
            departmentWhere = departmentWhere.And(x => x.Type == (int)Department_Type.矿山);
            if (_currentUser.CurrentUserInfo.LoginUserKuangShanDepartment.Item1 == false)
            {
                departmentWhere = departmentWhere.And(x => _currentUser.CurrentUserInfo.LoginUserKuangShanDepartment.Item2.Contains(x.DepartmentID));
            }
            var departments = _IDepartmentRepository.GetSearch(departmentWhere);

            var provinceIDs = departments.Where(x => x.ProvinceID.HasValue).Select(x => x.ProvinceID.Value).Distinct().ToList();
            var provinces = _provinceRepository.GetSearch(_provinceMapping.FilterModel2Where(new ProvinceFilterModel { _ProvinceIDs = provinceIDs }));

            return provinces.Select(x => new
            {
                Name = x.Name,
                Value = departments.Count(y => y.ProvinceID == x.ProvinceID)
            });
        }
        #endregion

        #region 获取各矿山钢丝绳总量
        public object GetAllDepartmentCnt()
        {
            //得到当前登录用户所对应的部门（矿山）信息
            var departmentWhere = Expressionable.Create<Department>();
            departmentWhere = departmentWhere.And(x => x.Type == (int)Department_Type.矿山);
            if (_currentUser.CurrentUserInfo.LoginUserKuangShanDepartment.Item1 == false)
            {
                departmentWhere = departmentWhere.And(x => _currentUser.CurrentUserInfo.LoginUserKuangShanDepartment.Item2.Contains(x.DepartmentID));
            }
            var departments = _IDepartmentRepository.GetSearch(departmentWhere);
            var departmentIDs = departments.Select(x => x.DepartmentID).ToList();

            //得到当前登录用户所对应的部门（矿山）中所包含的钢丝绳信息
            var usingWireropeWhere = Expressionable.Create<UsingWirerope>();
            usingWireropeWhere = usingWireropeWhere.And(x => x.Status == (int)UsingWirerope_Status.在用 && departmentIDs.Contains(x.DepartmentID));
            var usingWireropes = _IUsingWireropeRepository.GetSearch(usingWireropeWhere);

            //聚合矿山与钢丝数绳量数据
            var data = departments.Select(x => new
            {
                X = x.Name,
                Y = usingWireropes.Count(y => y.DepartmentID == x.DepartmentID),
                S = 1
            });

            return data;
        }
        #endregion

        #region 获取各指标下各状态钢丝绳数量（单个）
        public object GetStatusNameValue(string status)
        {
            //设置缓存key
            string cacheKey = $"{status}";
            //得到这个key在缓存中的值，可能会获取不到
            int? num = _cache.Get<int?>(cacheKey);

            if (!num.HasValue || num > 5)
            {
                num = 1;
            }

            var allData = _ICheckWireropeStatusMonitorRepository.GetInUsedAll(null);

            var cnt = -1;
            switch (status.ToLower())
            {
                case "la":
                    cnt = allData.Count(x => x.La.HasValue && x.La.Value == num);
                    break;

                case "dia":
                    cnt = allData.Count(x => x.Dia.HasValue && x.Dia.Value == num);
                    break;

                case "lma":
                    cnt = allData.Count(x => x.Lma.HasValue && x.Lma.Value == num);
                    break;

                case "ll":
                    cnt = allData.Count(x => x.NianJu.HasValue && x.NianJu.Value == num);
                    break;
            }

            _cache.Set(cacheKey, num + 1, TimeSpan.FromSeconds(60));

            return new { Prev = Gx.GetEnumName(typeof(StatusMonitorType), num.Value), Value = cnt };
        }
        #endregion

        #region 获取各指标项备注信息
        public object GetStatusRemark(string status)
        {
            var list = _standStatusRepository.GetAll();

            var remark = string.Empty;

            switch (status.ToLower())
            {
                case "la":
                    remark = list.First(x => x.Type == (int)StandStatus_Type.LA).Remark;
                    break;

                case "dia":
                    remark = list.First(x => x.Type == (int)StandStatus_Type.DIA).Remark;
                    break;

                case "lma":
                    remark = list.First(x => x.Type == (int)StandStatus_Type.LMA).Remark;
                    break;

                case "ll":
                    remark = list.First(x => x.Type == (int)StandStatus_Type.捻距变化).Remark;
                    break;
            }

            return new { Value = remark };
        }
        #endregion

        #region 获取各指标项个状态钢丝绳数量分布
        public object GetStatusPie(string status)
        {
            var allData = _ICheckWireropeStatusMonitorRepository.GetInUsedAll(null);
            int green = -1, blue = -1, yellow = -1, orange = -1, grey = -1;

            switch (status.ToLower())
            {
                case "la":
                    green = allData.Count(x => x.La.HasValue && x.La.Value == (int)StatusMonitor_LightType.绿);
                    blue = allData.Count(x => x.La.HasValue && x.La.Value == (int)StatusMonitor_LightType.蓝);
                    yellow = allData.Count(x => x.La.HasValue && x.La.Value == (int)StatusMonitor_LightType.黄);
                    orange = allData.Count(x => x.La.HasValue && x.La.Value == (int)StatusMonitor_LightType.橙);
                    grey = allData.Count(x => x.La.HasValue && x.La.Value == (int)StatusMonitor_LightType.灰);
                    break;

                case "dia":
                    green = allData.Count(x => x.Dia.HasValue && x.Dia.Value == (int)StatusMonitor_LightType.绿);
                    blue = allData.Count(x => x.Dia.HasValue && x.Dia.Value == (int)StatusMonitor_LightType.蓝);
                    yellow = allData.Count(x => x.Dia.HasValue && x.Dia.Value == (int)StatusMonitor_LightType.黄);
                    orange = allData.Count(x => x.Dia.HasValue && x.Dia.Value == (int)StatusMonitor_LightType.橙);
                    grey = allData.Count(x => x.Dia.HasValue && x.Dia.Value == (int)StatusMonitor_LightType.灰);
                    break;

                case "lma":
                    green = allData.Count(x => x.Lma.HasValue && x.Lma.Value == (int)StatusMonitor_LightType.绿);
                    blue = allData.Count(x => x.Lma.HasValue && x.Lma.Value == (int)StatusMonitor_LightType.蓝);
                    yellow = allData.Count(x => x.Lma.HasValue && x.Lma.Value == (int)StatusMonitor_LightType.黄);
                    orange = allData.Count(x => x.Lma.HasValue && x.Lma.Value == (int)StatusMonitor_LightType.橙);
                    grey = allData.Count(x => x.Lma.HasValue && x.Lma.Value == (int)StatusMonitor_LightType.灰);
                    break;

                case "ll":
                    green = allData.Count(x => x.NianJu.HasValue && x.NianJu.Value == (int)StatusMonitor_LightType.绿);
                    blue = allData.Count(x => x.NianJu.HasValue && x.NianJu.Value == (int)StatusMonitor_LightType.蓝);
                    yellow = allData.Count(x => x.NianJu.HasValue && x.NianJu.Value == (int)StatusMonitor_LightType.黄);
                    orange = allData.Count(x => x.NianJu.HasValue && x.NianJu.Value == (int)StatusMonitor_LightType.橙);
                    grey = allData.Count(x => x.NianJu.HasValue && x.NianJu.Value == (int)StatusMonitor_LightType.灰);
                    break;
            }

            return new List<object>()
            {
                new { name="轻度",value=green},
                new { name="中度",value=blue},
                new { name="重度",value=yellow},
                new { name="严重",value=orange},
                new { name="报废",value=grey},
            };
        }
        #endregion
    }
}
